/*
 * @Author: 鱿鱼溪学院
 * @Date: 2025-11-08 11:00:00
 * @LastEditTime: 2025-11-08 21:10:00
 * @LastEditors: 鱿鱼溪学院
 * @Description: 测试控制器，提供各种测试接口
 * @FilePath: \jmd-ser-ts\app\controller\TestController.ts
 * Copyright 鱿鱼溪学院 by edu v1.0
 * 天道酬勤
 */

import { Context } from 'koa'
import { query } from '../db/mysql'
import { AdminService } from '../service/AdminService'
import { ResponseUtil } from '../utils/ResponseUtil'
import {
  BadRequestException,
  UnauthorizedException,
  ForbiddenException,
  NotFoundException,
  InternalServerErrorException,
  ServiceException
} from '../exception'

import dbConfig from '../../config/config.db'

/**
 * 测试控制器类
 * 提供各种测试接口，用于验证系统功能
 */
export class TestController {
  /**
   * 基础测试接口
   * @description 返回一个简单的测试响应
   * @param ctx Koa上下文对象
   */
  public static async basicTest(ctx: Context): Promise<void> {
    return ResponseUtil.success(ctx, '基础测试成功')
  }

  /**
   * 数据库连接测试接口
   * @description 测试数据库连接是否正常
   * @param ctx Koa上下文对象
   * @returns 包含数据库版本信息的响应体
   * @url GET /api/test/db
   */
  public static async dbTest(ctx: Context): Promise<void> {
    try {
      // 执行一个简单的查询测试数据库连接
      const result = await query<{ version: string }>(
        'SELECT VERSION() as version'
      )
      ctx.body = {
        success: true,
        message: '数据库连接测试成功',
        data: {
          databaseVersion: result[0]?.version || '未知'
        }
      }
    } catch (error) {
      console.error('数据库测试失败:', error)
      ctx.status = 500
      ctx.body = {
        success: false,
        message: '数据库连接测试失败',
        error: (error as Error).message
      }
    }
  }

  /**
   * 环境变量测试接口
   * @description 返回当前环境配置信息
   * @param ctx Koa上下文对象
   * @returns 包含环境变量信息的响应体
   * @url GET /api/test/env
   */
  public static async envTest(ctx: Context): Promise<void> {
    ctx.body = {
      success: true,
      message: '环境变量测试',
      data: {
        databaseHost: dbConfig.db_host || 'localhost', // 从配置中获取数据库主机
        databasePort: dbConfig.db_port ? Number(dbConfig.db_port) : 3306, // 从配置中获取数据库端口
        databaseUser: dbConfig.db_user || 'root', // 从配置中获取数据库用户名
        databasePassword: dbConfig.db_pwd || '', // 从配置中获取数据库密码
        nodeEnv: process.env.NODE_ENV || '未设置',
        port: process.env.PORT || '未设置',
        host: process.env.HOST || '未设置',
        isDevelopment: process.env.NODE_ENV === 'development'
      }
    }
  }

  /**
   * 延迟响应测试接口
   * @description 模拟异步操作，延迟返回结果
   * @param ctx Koa上下文对象
   */
  public static async delayTest(ctx: Context): Promise<void> {
    const delay = parseInt(ctx.query.delay as string) || 1000

    await new Promise((resolve) => setTimeout(resolve, delay))

    ctx.body = {
      success: true,
      message: `延迟 ${delay}ms 后响应`,
      timestamp: new Date().toISOString()
    }
  }

  /**
   * 管理员查询接口
   * @description 根据ID查询管理员信息
   * @param ctx Koa上下文对象
   */
  public static async adminFind(ctx: Context): Promise<void> {
    const adminId = parseInt(ctx.query.id as string)
    console.log('查询管理员ID:', adminId)

    // 验证参数
    if (!adminId || isNaN(adminId)) {
      return ResponseUtil.badRequest(ctx, '无效的管理员ID')
    }

    const admin = await AdminService.getAdminById(adminId)
    if (!admin) {
      return ResponseUtil.notFound(ctx, `管理员 ${adminId} 不存在`)
    }

    return ResponseUtil.success(ctx, `查询管理员 ${adminId} 成功`, admin)
  }

  /**
   * 管理员创建接口
   * @description 创建一个新的管理员
   * @param ctx Koa上下文对象
   */
  public static async adminCreate(ctx: Context): Promise<void> {
    try {
      // 创建测试管理员
      const testAdminData = {
        username: `test_admin_${Date.now()}`,
        password: 'test_password',
        avatar: 'https://example.com/avatar.jpg',
        description: '测试管理员',
        email: 'test@example.com',
        phone: '13800138000',
        status: 1
      }

      const createdAdmin = await AdminService.createAdmin(testAdminData)
      console.log('创建管理员成功:', createdAdmin.id)
      return ResponseUtil.success(ctx, '创建管理员成功', createdAdmin)
    } catch (error) {
      console.error('创建管理员失败:', error)
      return ResponseUtil.error(
        ctx,
        `创建管理员失败: ${(error as Error).message}`
      )
    }
  }
  /**
   * 管理员服务测试接口
   * @description 测试管理员服务的各种功能
   * @param ctx Koa上下文对象
   */
  public static async adminServiceTest(ctx: Context): Promise<void> {
    try {
      // 创建测试管理员
      const testAdminData = {
        username: `test_admin_${Date.now()}`,
        password: 'test_password',
        avatar: 'https://example.com/avatar.jpg',
        description: '测试管理员',
        email: 'test@example.com',
        phone: '13800138000',
        status: 1
      }

      const createdAdmin = await AdminService.createAdmin(testAdminData)
      console.log('创建管理员成功:', createdAdmin.id)

      // 根据ID查询管理员
      const foundAdmin = await AdminService.getAdminById(createdAdmin.id)
      console.log('根据ID查询管理员成功:', foundAdmin?.username)

      // 获取管理员列表
      const adminList = await AdminService.getAdminList()
      console.log('管理员列表数量:', adminList.list.length)

      // 更新管理员信息
      const updatedAdmin = await AdminService.updateAdmin(createdAdmin.id, {
        description: '更新后的测试管理员',
        phone: '13900139000'
      })
      console.log('更新管理员成功:', updatedAdmin.description)

      // 验证登录（仅测试，实际应该使用加密密码）
      const loginResult = await AdminService.verifyLogin(
        testAdminData.username,
        testAdminData.password
      )
      console.log('登录验证结果:', loginResult.success)

      // 清理测试数据
      // await AdminService.deleteAdmin(createdAdmin.id);

      return ResponseUtil.success(ctx, '管理员服务测试成功', {
        createdAdmin,
        foundAdmin,
        adminListCount: adminList.list.length,
        updatedAdmin,
        loginResult
      })
    } catch (error) {
      console.error('管理员服务测试失败:', error)
      return ResponseUtil.error(
        ctx,
        `管理员服务测试失败: ${(error as Error).message}`
      )
    }
  }

  /**
   * 异常演示接口
   * @description 演示各种异常的使用方式
   * @param ctx Koa上下文对象
   * @url GET /api/test/exception?type=[badRequest|unauthorized|forbidden|notFound|serverError|serviceError]
   */
  public static async exceptionTest(ctx: Context): Promise<void> {
    const exceptionType = (ctx.query.type as string) || 'badRequest'

    // return ResponseUtil.success(
    //   ctx,
    //   `异常演示成功，异常类型为 ${exceptionType}`
    // )

    console.log('异常类型:', exceptionType)
    // 演示404错误 - 资源未找到

    try {
      // 模拟异步操作，延迟返回结果
      throw new NotFoundException('请求的用户不存在', 40401, {
        userId: ctx.query.id || 'unknown'
      })
    } catch (error) {
      // 记录日志后重新抛出异常，让全局错误处理器处理
      console.error('捕获到异常，重新抛出以便全局错误处理器处理:', error)
      //  throw error
    }

    // 根据查询参数抛出不同类型的异常
    switch (exceptionType) {
      case 'badRequest':
        // 演示400错误 - 请求参数错误
        throw new BadRequestException('请求参数验证失败', 40001, {
          fieldErrors: [
            { field: 'username', message: '用户名不能为空' },
            { field: 'password', message: '密码长度不能小于6位' }
          ]
        })

      case 'unauthorized':
        // 演示401错误 - 未授权
        throw new UnauthorizedException('用户未登录或登录已过期', 40101)

      case 'forbidden':
        // 演示403错误 - 权限不足
        throw new ForbiddenException('您没有权限执行此操作', 40301, {
          requiredPermission: 'admin:edit'
        })

      case 'notFound':
        // 演示404错误 - 资源未找到
        throw new NotFoundException('请求的用户不存在', 40401, {
          userId: ctx.query.id || 'unknown'
        })

      case 'serverError':
        // 演示500错误 - 服务器内部错误
        throw new InternalServerErrorException('数据库操作失败')

      case 'serviceError':
        // 演示业务逻辑错误
        throw new ServiceException('用户名已存在，请更换其他用户名', 40002)

      default:
        // 默认演示基础错误响应
        return ResponseUtil.success(
          ctx,
          '请指定异常类型参数: ?type=[badRequest|unauthorized|forbidden|notFound|serverError|serviceError]',
          {
            availableTypes: [
              'badRequest',
              'unauthorized',
              'forbidden',
              'notFound',
              'serverError',
              'serviceError'
            ]
          }
        )
    }
  }

  public static async test(ctx: Context): Promise<void> {
    throw new BadRequestException('请求参数错误', 40001, {
      fieldErrors: [
        { field: 'username', message: '用户名不能为空' },
        { field: 'password', message: '密码长度不能小于6位' }
      ]
    })
  }

  /**
   * 更多测试功能...
   * @param ctx Koa上下文对象
   */
  public static async moreTest(ctx: Context): Promise<void> {
    ctx.body = {
      success: true,
      message: '更多测试功能',
      timestamp: new Date().toISOString(),
      features: ['管理员服务', '数据操作', '业务逻辑']
    }
  }

  /**
   * 错误处理测试接口
   * @description 测试错误处理机制
   * @param ctx Koa上下文对象
   */
  public static async errorTest(ctx: Context): Promise<void> {
    const errorType = ctx.query.type as string

    switch (errorType) {
      case '400':
        ctx.status = 400
        ctx.body = { success: false, message: '请求参数错误' }
        break
      case '401':
        ctx.status = 401
        ctx.body = { success: false, message: '未授权访问' }
        break
      case '403':
        ctx.status = 403
        ctx.body = { success: false, message: '禁止访问' }
        break
      case '404':
        ctx.status = 404
        ctx.body = { success: false, message: '请求的资源不存在' }
        break
      case '500':
        throw new Error('测试服务器内部错误')
      default:
        ctx.body = {
          success: true,
          message: '错误处理测试接口',
          availableTypes: ['400', '401', '403', '404', '500']
        }
    }
  }
}
